<template>
  <div class="container">
    <div class="app-container">
      <div class="left">
        <el-input v-model="keyword" style="margin-bottom:10px" type="text" prefix-icon="el-icon-search" size="small" placeholder="输入员工姓名全员搜索" @input="onSearch" />
        <!-- 树形组件 -->
        <!-- tree在element中默认label的属性名是label，后台数据不应是label，所以用：props={label:'后台数据名' } -->
        <el-tree ref="treeRef" node-key="id" highlight-current :props="{label:'name'}" :data="treeList" default-expand-all :expand-on-click-node="false" @current-change="onChangeTree" />
        <!--2.选中节点高亮
          1.highlight-current  选的中当前节点高亮
          2.打开页面默认父节点高亮
          3.设置标识符node-key：id，和refs元素里面的方法默认打开页面默认那个元素高亮
          4.在数据获取到时，使用$nextTick(()=>{this.$refs.})
          5.this.$refs.treeRef.setCurrentKey(list[0 ])  //括号里面的的id会对应当前node-key的id，给他默认被选中
          -->
      </div>
      <div class="right">
        <el-row class="opeate-tools" type="flex" justify="end">
          <el-button v-button="'add-employee'" size="mini" type="primary" @click="$router.push('/employee/detail')">添加员工</el-button>
          <el-button size="mini" @click="showExcelDialog = true">excel导入</el-button> <!-- 导入文件显示弹出层 -->
          <el-button size="mini" @click="onExport">excel导出</el-button>
        </el-row>
        <!-- 表格组件 -->
        <el-table v-loading="loading" :header-cell-style="{background:'#f5f6f8'}" :data="tableList">
          <el-table-column type="selection" />
          <el-table-column label="头像" width="120">
            <template #default="{row}">
              <el-avatar v-if="row.staffPhoto" :src="row.staffPhoto" size="medium" alt="" />
              <span v-else class="username">555</span>
            </template>
          </el-table-column>
          <el-table-column prop="username" label="姓名" width="164" />
          <el-table-column prop="mobile" label="手机号" width="164" sortable />
          <el-table-column prop="workNumber" label="工号" width="164" sortable />
          <el-table-column label="聘用形式" width="164">
            <template #default="{row}">
              {{ row.formOfEmployment ===1? '正式' :'非正式' }}
            </template>
          </el-table-column>
          <el-table-column prop="departmentName" label="部门" width="164" />
          <el-table-column prop="timeOfEntry" label="入职时间" width="164" sortable />
          <el-table-column label="操作">
            <template #default="{row}">
              <el-button type="text" @click="$router.push('/employee/detail/' + row.id)">查看</el-button>
              <el-button type="text" style="margin-right: 10px;" @click="onshowRole(row.id)">角色</el-button>
              <!-- 删除按钮 -->
              <el-popconfirm
                title="这是一段内容确定删除吗？"
                @onConfirm="onDel(row.id)"
              >
                <el-button slot="reference" type="text">删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页 -->
        <el-row type="flex" justify="end" style="margin-top: 20px;">
          <el-pagination layout="total,prev,pager,next" :current-page="page" :total="total" @current-change="onChangePage" />
        </el-row>
      </div>

      <!-- 导入弹出层 -->
      <ExcelDialog :show-excel-dialog.sync="showExcelDialog" @success="onloadEmployee" />

      <!-- 添加角色弹出层 -->
      <el-dialog title="分配角色" :visible.sync="visible">

        <el-checkbox-group v-model="roleIds">  <!-- v-model绑定的是一个数组 -->
          <el-checkbox v-for="item in roleList" :key="item.id" :label="item.id">{{ item.name }}</el-checkbox>
        </el-checkbox-group>

        <template #footer>
          <el-row type="flex" justify="center">
            <el-button type="primary" @click="onUpdate">确定</el-button>
            <el-button @click="visible = false">取消</el-button>
          </el-row>
        </template>
      </el-dialog>
    </div>
  </div>
</template>
<!-- 1.渲染左边树状图

 -->

<!-- 3.渲染右边表格
  1.封装api
  2.在method里面封装调用api的方法，传参看调用接口的参数，在data定义
  3.当在页面打开时候定义一个部门id，把数组的第0位索引的部门id传给data，在发请求
  4.在tree上面有个自定义事件current-change，监听到切换到那个元素，第一个参数能拿到该元素的所有数据，就有部门id
  5.当这个事件触发时，把他身上的部门id赋值给data的部门id
  6.在发一次渲染列表请求，就能拿到该部门的所有数据
 -->

 <!-- 4.表格分页和左树的关联
  -->

  <!-- 5.在输入框模糊搜索
    1.v-model双向绑定获取name的数据
    2.在封装列表的时候把这个api传入
    3.当用户输入暂停时调用列表请求，使用防抖进行能优化
   -->

   <!--6.导出文件
    1.封装api，responseType = blob
    2.request响应拦截做判断，if（response.data instanceof Blob）return response.data
    3.在使用的页面中引入file-saver的方法 {saveAs}
    4.当返回的数据是二进制的直接 saveAs([res],‘员工数据列表.xlsx)  数据是用数组放入
    5.如果不是二进制，就要转译为二进制 new Blob([res], { type: 'text/plain;charset=utf-8' })
    -->

    <!-- 7.点击添加员工
      1.在组件的index.vue旁边创建一个详情组件
      2.配置路由在员工的children里面
      3.在employee点击元素跳转到详情页，$router.push('/employee/detail')
     -->

     <!-- 8.点击添加跳转其他界面
      1.在components子模块添加一个detail模块
      2.在路由配置项配置在employee下，metal的title名可以写，hidden为true
      3.在点击添加按钮时跳转路由
      4.传递数据根据父传子，子传父接收并刷新界面
      5.当跳转路由时判断有没有传递过来id，有id就是编辑，需要发请求获取当前数据详情进行数据回填
      6.如果没有id，提交添加员工成功时发请求跳转到员工列表界面
      -->

     <!-- 9.级联选择器使用
      1.封装组件
      2.在detail引入进来
      3.使用将后台返回数据生成树状结构赋值为options，里面数据如果value是id，label名是name名要用 :props:{label:'name',value:'id'}进行修改
      4.在detail的模块中用v-model绑定进行父传子
      5.子模块:value接受数据，:value=value,利用change事件的事件对象接受收选择的数据，事件对象返回的数据是数组，我们需要拿到最后一个数据，$event[$event.length - 1]
      6.使用 $emit传递回去给父组件detail， $emit('input',$event[$event.length - 1])
      -->

 <!--10.点击角色给员工添加角色
  1.创建弹出层组件
  2.使用:visible.sync=visible
  3.点击角色弹出弹出层,每个用户id不一致，点击那个用户提交不同的id
  -->

  <!--11.获取已启用角色列表
    1.封装api获取已启用的角色列表
    2.点击打开弹出层时发请求获取列表
    3.data定义角色列表数据和选中的角色返回id（value）数组
    4.使用element-ui的checkbox-group 的v-model绑定角色数组 和子元素checkbox的选中使用:label绑定id，显示文字使用插值渲染
    5.选中时v-model绑定的数组会返回选中的id的数组
   -->

<!--12.点击角色进行回回显然后点击确认对用户角色进行更新
1.复用以前的查询角色列表，获取已有的角色id数组进行回显
2.封装api，当户用选择好角色点击确认时，进行更新角色，需要传id和选中角色id数组
3.添加角色成功提示用户，关闭模态框
 -->

 <!--💥💥💥不需要动态渲染的id，可以直接用this挂载到vue上面 -->
<script>
import { getDepartmentListAPI } from '@/api/department'
import { convertToTree } from '@/utils'
import { delEmployeeAPI, exportEmployeeAPI, getEmployeeDetailAPI, getEmployeeListAPI, getEnableListAPI } from '@/api/employee'
import ExcelDialog from '@/views/employee/components/ExcelDialog.vue'
// 引入file-saver的方法
import { saveAs } from 'file-saver'
import { assignRoleAPI } from '@/api/role'
// 定时器
let timer = null
export default {
  name: 'Employee',
  components: { ExcelDialog },
  data() {
    return {
      showExcelDialog: false, // 导入弹出层显示与隐藏
      loading: false,
      treeList: [],
      tableList: [],
      // tablelist参数
      page: 1,
      pagesize: 10,
      keyword: '',
      departmentId: null,
      total: 0,
      visible: false,
      roleList: [], // 已启用角色列表
      roleIds: [] // 选中的id
    }
  },
  async created() {
    const { data } = await getDepartmentListAPI()
    const tree = convertToTree(data, 0)
    this.treeList = tree
    // 获取初次table的数据
    this.departmentId = tree[0].id
    this.onloadEmployee()

    this.$nextTick(() => {
      // 因为数据是同步的，dom渲染是异步的
      this.$refs.treeRef.setCurrentKey(this.treeList[0])
    })
  },
  methods: {
    // 获取表格列表数据
    async onloadEmployee() {
      this.loading = true
      const { data } = await getEmployeeListAPI({
        page: this.page,
        pagesize: this.pagesize,
        keyword: this.keyword,
        departmentId: this.departmentId
      })
      this.tableList = data.rows
      this.total = data.total
      this.loading = false
    },
    // 模糊搜索请求
    onSearch() {
      clearTimeout(timer)
      timer = setTimeout(() => {
        this.onloadEmployee()
      }, 1000)
    },
    // 切换当前树的元素
    onChangeTree(row) {
      this.page = 1
      this.keyword = ''
      this.departmentId = row.id
      this.onloadEmployee()
    },
    // 切换页数,当切换页数时，要把page更改为1
    onChangePage(val) {
      this.page = val
      this.onloadEmployee()
    },
    // 删除员工
    async onDel(id) {
      await delEmployeeAPI(id)
      this.$message.success('删除成功')
      if (this.tableList.length === 1) {
        this.page--
      }
      this.onloadEmployee()
    },
    // 导入export方法
    async onExport() {
      // res数据就是二进制的内容
      const res = await exportEmployeeAPI()
      // 先转译为二进制数据
      // const blob = new Blob([res], { type: 'text/plain;charset=utf-8' })
      console.log('res  --->', res)
      saveAs(res, '员工数据列表.xlsx')
    },
    // 分配角色
    onshowRole(id) {
      // // 获取一起用角色列表
      // const { data } = await getEnableListAPI()
      // // 获取用户的信息详情有分配的角色id数组
      // const {data} = await getEmployeeDetailAPI(id)
      Promise.all([getEnableListAPI(), getEmployeeDetailAPI(id)])
        .then(([{ data: roleList }, { data: { roleIds }}]) => { // 无线解构
          this.roleList = roleList
          this.roleIds = roleIds
          this.visible = true
        })
        .catch((err) => {
          console.log('err  --->', err)
        })
      this.id = id
      // 获取用户的选中的角色
      // this.roleList = data
      // this.visible = true
    },
    // 更新用户角色
    async onUpdate() {
      await assignRoleAPI({
        id: this.id,
        roleIds: this.roleIds
      })
      this.$message.success('修改角色成功')
      this.visible = false
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  background: #fff;
  display: flex;
  .left {
    width: 280px;
    padding: 20px;
    border-right: 1px solid #eaeef4;
  }
  .right {
    flex: 1;
    padding: 20px;
    .opeate-tools {
      margin:10px ;
    }
    .username {
      height: 30px;
      width: 30px;
      line-height: 30px;
      text-align: center;
      border-radius: 50%;
      color: #fff;
      background: #04C9BE;
      font-size: 12px;
      display:inline-block;
    }
  }
}

</style>
